package net.awpspace.matheasy;

import java.io.IOException;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.microedition.content.ContentHandlerException;
import javax.microedition.content.Invocation;
import javax.microedition.content.Registry;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;

public class GameScreen extends GameCanvas {

	public static final int PREPARE_GAME = 1;
	public static final int START_GAME = 2;
	public static final int PAUSE_GAME = 3;
	public static final int RESUME_GAME = 4;
	public static final int END_GAME = 5;

	public int stateGame = PREPARE_GAME;

	Image background, imAdd1, imAdd2, imSub1, imSub2, imDiv1, imDiv2, imMulti1,
			imMulti2, label, value, imtime, bgPause, pauseup, pausedown,
			imNumber, atob, btoa, atoc, ctoa, btoc, ctob;
	Button add, sub, div, multi, pause;
	Label number1, number2, result, countResult;
	MySprite time1, time2;
	int resultRight = 0;
	Calculate cal = new Calculate();
	TimerTask task;
	Timer timer;
	int time = 61;
	boolean loop = true;

	Prepare prepare;
	EndGame endgame;
	MathEasy main;

	Command back;

	protected GameScreen(MathEasy main) {
		super(true);
		this.main = main;
		setFullScreenMode(true);
		loadContent();
		setListener();
		prepare = new Prepare();
		prepare.isVisible = true;
		endgame = new EndGame();
		endgame.isVisible = false;
		timer = new Timer();

		back = new Command("back", Command.BACK, 1);
		addCommand(back);
		setCommandListener(new CommandListener() {

			public void commandAction(Command c, Displayable d) {
				if (c.getLabel().equals("back")) {
					showDialog();
				}
			}
		});
	}

	private void loadContent() {
		background = ImageLoader.loadImage("/background.png");
		imAdd1 = ImageLoader.loadImage("/add.png");
		imAdd2 = ImageLoader.loadImage("/add1.png");
		imSub1 = ImageLoader.loadImage("/sub.png");
		imSub2 = ImageLoader.loadImage("/sub1.png");
		imDiv1 = ImageLoader.loadImage("/div.png");
		imDiv2 = ImageLoader.loadImage("/div1.png");
		imMulti1 = ImageLoader.loadImage("/multi.png");
		imMulti2 = ImageLoader.loadImage("/multi1.png");
		imtime = ImageLoader.loadImage("/time.png");
		value = ImageLoader.loadImage("/value.png");
		label = ImageLoader.loadImage("/label.png");
		bgPause = ImageLoader.loadImage("/bgpause.png");
		pauseup = ImageLoader.loadImage("/pause.png");
		pausedown = ImageLoader.loadImage("/pausedown.png");
		atob = ImageLoader.loadImage("/atob.png");
		btoa = ImageLoader.loadImage("/btoa.png");
		atoc = ImageLoader.loadImage("/atoc.png");
		ctoa = ImageLoader.loadImage("/ctoa.png");
		btoc = ImageLoader.loadImage("/btoc.png");
		ctob = ImageLoader.loadImage("/ctob.png");

		imNumber = ImageLoader.loadImage("/number.png");

		time1 = new MySprite(imNumber, 10, 1, 190, 27);
		time2 = new MySprite(imNumber, 10, 1, 207, 27);
		add = new Button(imAdd1, imAdd2, 45, 198);
		div = new Button(imDiv1, imDiv2, 142, 260);
		multi = new Button(imMulti1, imMulti2, 45, 260);
		sub = new Button(imSub1, imSub2, 142, 198);
		pause = new Button(pauseup, pausedown, 5, 5);

		number1 = new Label(label, 10, 85);
		number2 = new Label(label, 165, 85);
		result = new Label(label, 85, 140);
		countResult = new Label(label, 85, 27);
		countResult.setLabel("0");
		countResult.offsetX = offset(countResult.label);

	}

	public void startGame() {
		stateGame = START_GAME;
		System.out.println("st: " + stateGame);
		loop = true;
		task = new TimerTask() {

			public void run() {
				while (loop) {
					time--;
					convertTime();
					repaint();
					if (time == 0) {
						loop = false;
						endgame();
					}
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		};
		timer.schedule(task, 1);
	}

	public void retry() {
		main.display.setCurrent(new GameScreen(main));
	}

	protected void showNotify() {
		super.showNotify();
		System.out.println("Show Notify");
	}

	protected void hideNotify() {
		super.hideNotify();
		if (stateGame == START_GAME) {
			stateGame = PAUSE_GAME;
			loop = false;
			System.out.println("Hide notify");
		}
	}

	protected void convertTime() {
		int t1 = time / 10;
		int t2 = time % 10;
		time1.setFrame(t1);
		time2.setFrame(t2);
	}

	public void showDialog() {
		Alert dialog = new Alert("Are you really to quit!");
		dialog.addCommand(new Command("ok", Command.OK, 1));
		dialog.addCommand(new Command("cancel", Command.CANCEL, 1));
		dialog.setCommandListener(new CommandListener() {

			public void commandAction(Command c, Displayable d) {
				if (c.getLabel().equals("ok")) {
					main.display.setCurrent(new MenuScreen(main));
				} else if (c.getLabel().equals("cancel")) {
					main.display.setCurrent(GameScreen.this);
				}
			}
		});
		main.display.setCurrent(dialog, this);
	}

	private void endgame() {
		stateGame = END_GAME;
		loop = false;
		cal.typeIndex = -1;
		endgame.isVisible = true;
		endgame.setScore();
	}

	public void setListener() {
		add.setListener(new ButtonListener() {
			public void actionUp() {
				if (cal.operator == Calculate.ADD) {
					resultRight++;
					countResult.setLabel(resultRight + "");
					countResult.offsetX = offset(countResult.label);
					setValue();
					System.out.println("add");
				} else {
					endgame();

				}
				super.actionUp();

			}
		});
		sub.setListener(new ButtonListener() {
			public void actionUp() {
				if (cal.operator == Calculate.SUB) {
					resultRight++;
					countResult.setLabel(resultRight + "");
					countResult.offsetX = offset(countResult.label);
					setValue();
					System.out.println("sub");
				} else
					endgame();
				super.actionUp();

			}
		});
		div.setListener(new ButtonListener() {
			public void actionUp() {
				if (cal.operator == Calculate.DIV) {
					resultRight++;
					countResult.setLabel(resultRight + "");
					countResult.offsetX = offset(countResult.label);
					setValue();
					System.out.println("div");
				} else
					endgame();
				super.actionUp();

			}
		});
		multi.setListener(new ButtonListener() {
			public void actionUp() {
				if (cal.operator == Calculate.MUL) {
					resultRight++;
					countResult.setLabel(resultRight + "");
					countResult.offsetX = offset(countResult.label);
					setValue();
					System.out.println("multi");
				} else
					endgame();
				super.actionUp();

			}
		});
		pause.setListener(new ButtonListener() {
			public void actionUp() {
				super.actionUp();
				stateGame = PAUSE_GAME;
				loop = false;
			}
		});
	}

	/**
	 * 1 chu so: offsetX = 25; 2 chu so: offsetX = 20; 3 chu so: offsetX = 17; 4
	 * chu so: offsetX = 15; 5 chu so: offsetX = 11;
	 * 
	 */

	public void setValue() {
		cal.prepareCalculate();
		switch (cal.typeIndex) {
		case 0:
			number1.setLabel(cal.number1 + "");
			number2.setLabel(cal.number2 + "");
			result.setLabel(cal.result + "");
			break;
		case 1:
			number1.setLabel(cal.number1 + "");
			number2.setLabel(cal.result + "");
			result.setLabel(cal.number2 + "");

			break;
		case 2:
			number1.setLabel(cal.result + "");
			number2.setLabel(cal.number2 + "");
			result.setLabel(cal.number1 + "");
			break;
		case 3:
			number1.setLabel(cal.number2 + "");
			number2.setLabel(cal.number1 + "");
			result.setLabel(cal.result + "");
			break;
		case 4:
			number1.setLabel(cal.result + "");
			number2.setLabel(cal.number1 + "");
			result.setLabel(cal.number2 + "");
			break;

		case 5:
			number1.setLabel(cal.number2 + "");
			number2.setLabel(cal.result + "");
			result.setLabel(cal.number1 + "");
			break;

		default:
			break;
		}
		number1.offsetX = offset(number1.label);
		number2.offsetX = offset(number2.label);
		result.offsetX = offset(result.label);
		repaint();
	}

	public int offset(String s) {
		switch (s.length()) {
		case 1:
			return 25;
		case 2:
			return 20;
		case 3:
			return 17;
		case 4:
			return 15;
		case 5:
			return 11;
		case 6:
			return 7;
		default:
			return 0;
		}
	}

	public void paint(Graphics g) {
		super.paint(g);
		g.fillRect(0, 0, 240, 320);
		g.drawImage(background, 0, 0, Graphics.TOP | Graphics.LEFT);
		add.draw(g);
		div.draw(g);
		multi.draw(g);
		sub.draw(g);
		pause.draw(g);

		g.drawImage(value, 92, 74, 0);
		g.drawImage(imtime, 177, 16, 0);
		number1.draw(g);
		number2.draw(g);
		result.draw(g);
		countResult.draw(g);

		time1.paint(g);
		time2.paint(g);
		drawDirect(g);

		prepare.draw(g);

		if (stateGame == PAUSE_GAME)
			g.drawImage(bgPause, 41, 117, 0);
		if (stateGame == END_GAME)
			endgame.draw(g);

	}

	private void drawDirect(Graphics g) {
		switch (cal.typeIndex) {
		case 0:
			g.drawImage(atob, 64, 84, 0);
			break;
		case 1:
			g.drawImage(atoc, 33, 105, 0);
			break;
		case 2:
			g.drawImage(ctob, 147, 115, 0);
			break;
		case 3:
			g.drawImage(btoa, 64, 84, 0);
			break;
		case 4:
			g.drawImage(btoc, 147, 115, 0);
			break;

		case 5:
			g.drawImage(ctoa, 33, 105, 0);
			break;

		default:
			break;
		}

	}

	protected void pointerPressed(int x, int y) {
		super.pointerPressed(x, y);

		if (stateGame == PAUSE_GAME) {
			startGame();
		} else if (stateGame == PREPARE_GAME) {
			prepare.play.actionDown(x, y);
			System.out.println("state : " + stateGame);
		} else if (stateGame == START_GAME) {
			pause.actionDown(x, y);
			add.actionDown(x, y);
			div.actionDown(x, y);
			multi.actionDown(x, y);
			sub.actionDown(x, y);
		} else if (stateGame == END_GAME) {
			endgame.touchDown(x, y);
		}
		repaint();
	}

	protected void pointerReleased(int x, int y) {
		super.pointerReleased(x, y);
		if (stateGame == PREPARE_GAME)
			prepare.play.actionUp(x, y);
		else if (stateGame == START_GAME) {
			pause.actionUp(x, y);
			add.actionUp(x, y);
			div.actionUp(x, y);
			multi.actionUp(x, y);
			sub.actionUp(x, y);
		} else if (stateGame == END_GAME)
			endgame.touchUp(x, y);
		repaint();
	}

	class Calculate {
		public static final int ADD = '+';
		public static final int SUB = '-';
		public static final int MUL = '*';
		public static final int DIV = '/';
		public int number1;
		public int number2;
		public int result;
		public int operator;
		Random ran = new Random();
		public int mode = 1;
		int typeIndex = -1;
		public int type[][] = { { 1, 2, 3 }, { 1, 3, 2 }, { 3, 2, 1 },
				{ 2, 1, 3 }, { 2, 3, 1 }, { 3, 1, 2 } };

		// mode = 1 easy; mode = 2 normal; mode = 3 difficult
		public Calculate() {
		}

		public void prepareCalculate() {
			typeIndex = ran.nextInt(6);
			int op = ran.nextInt(4);
			System.out.println("Op: " + op + "type index: " + typeIndex);
			switch (op) {
			case 0:
				operator = ADD;
				add();
				break;
			case 1:
				operator = SUB;
				sub();
				break;
			case 2:
				operator = MUL;
				mul();
				break;
			case 3:
				operator = DIV;
				div();
				break;

			default:
				break;
			}
		}

		public void add() {
			ran.setSeed(ran.nextInt(999999));
			number1 = ran.nextInt(2222) + ran.nextInt(2222);
			number2 = ran.nextInt(2222) + ran.nextInt(2222);
			result = number1 + number2;
			System.out.println(number1 + "+" + number2 + "=" + result);
		}

		public void sub() {
			ran.setSeed(ran.nextInt(999999));
			number1 = ran.nextInt(4444) + ran.nextInt(5555);
			number2 = ran.nextInt(2222) + ran.nextInt(3333);
			result = number1 - number2;
			System.out.println(number1 + "-" + number2 + "=" + result);
		}

		public void mul() {
			ran.setSeed(ran.nextInt(999999));
			number1 = ran.nextInt(444) + ran.nextInt(555);
			number2 = ran.nextInt(222) + ran.nextInt(33);
			result = number1 * number2;
			System.out.println(number1 + "*" + number2 + "=" + result);
		}

		public void div() {
			ran.setSeed(ran.nextInt(999999));
			mul();
			int tmp1 = number1;
			int tmp2 = number2;
			int res = result;
			number1 = res;
			number2 = tmp1;
			result = tmp2;
			System.out.println(number1 + "/" + number2 + "=" + result);
		}
	}

	class Prepare {
		Image bgblack, bgprepare, startup, startdown;
		public boolean isVisible;
		Button play;

		public Prepare() {
			loadContent();
		}

		private void loadContent() {
			bgblack = ImageLoader.loadImage("/bgblack.png");
			bgprepare = ImageLoader.loadImage("/bgprepare.png");
			System.out.println((bgblack.getWidth()) + "  "
					+ (bgprepare.getHeight()));
			startup = ImageLoader.loadImage("/startup.png");
			startdown = ImageLoader.loadImage("/startdown.png");

			play = new Button(startup, startdown, 80, 173);
			play.setListener(new ButtonListener() {
				public void actionUp() {
					super.actionUp();
					if (stateGame == PREPARE_GAME) {
						isVisible = false;
						startGame();
						setValue();
						repaint();
					}
				}
			});
		}

		public void draw(Graphics g) {

			if (isVisible) {
				g.drawImage(bgblack, 0, 0, 0);
				g.drawImage(bgprepare, 33, 74, 0);
				play.draw(g);
			}
		}
	}

	class EndGame {
		Image bgendgame, imrety, imretrydown, imshare, imsharedown, imexit,
				imexitdown;
		Button retry, share, exit;
		public boolean isVisible = false;
		Vector score;

		public EndGame() {
			loadContent();
		}

		private void loadContent() {
			bgendgame = ImageLoader.loadImage("/bgendgame.png");
			imrety = ImageLoader.loadImage("/retry.png");
			imretrydown = ImageLoader.loadImage("/retrydown.png");
			imshare = ImageLoader.loadImage("/shareface.png");
			imsharedown = ImageLoader.loadImage("/facedown.png");
			imexit = ImageLoader.loadImage("/exit.png");
			imexitdown = ImageLoader.loadImage("/exitdown.png");

			retry = new Button(imrety, imretrydown, 45, 205);
			share = new Button(imshare, imsharedown, 99, 205);
			exit = new Button(imexit, imexitdown, 152, 205);

			retry.setListener(new ButtonListener() {
				public void actionUp() {
					super.actionUp();
					retry();
				}
			});

			share.setListener(new ButtonListener() {
				public void actionUp() {
					// TODO Auto-generated method stub
					super.actionUp();
					share();
				}
			});

			exit.setListener(new ButtonListener() {
				public void actionUp() {
					// TODO Auto-generated method stub
					super.actionUp();
					main.display.setCurrent(new MenuScreen(main));
				}
			});
		}

		public void share() {
			String[] args = new String[] { "text="
					+ "I passed "
					+ resultRight
					+ " challenge in Math Easy :D.\nLet's play with me.\nhttp://store.ovi.com/publisher/withlovei/" };
			String mime = "text/plain";
			Registry registry = Registry.getRegistry(main.getClass().getName());
			Invocation invocation = new Invocation(null, mime,
					"com.nokia.share");
			invocation.setAction("share");
			invocation.setArgs(args);
			invocation.setResponseRequired(false);
			try {
				registry.invoke(invocation);
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ContentHandlerException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("Share");
		}

		private void setScore() {
			score = new Vector();
			String str = resultRight + "";
			System.out.println("AAA: " + str);
			int w = 25, h = 17;
			int anchorX = (240 - str.length() * 25) / 2;
			for (int i = 0; i < str.length(); i++) {
				MySprite sp = new MySprite(imNumber, 10, 1, anchorX + i * w,
						158);
				sp.setFrame(str.charAt(i) - 48);
				score.addElement(sp);
			}
		}

		public void touchUp(int x, int y) {
			retry.actionUp(x, y);
			share.actionUp(x, y);
			exit.actionUp(x, y);

		}

		public void touchDown(int x, int y) {
			retry.actionDown(x, y);
			share.actionDown(x, y);
			exit.actionDown(x, y);
		}

		public void draw(Graphics g) {
			if (isVisible) {
				g.drawImage(bgendgame, 39, 87, 0);
				retry.draw(g);
				share.draw(g);
				exit.draw(g);
				for (int i = 0; i < score.size(); i++)
					((MySprite) score.elementAt(i)).paint(g);
			}
		}

	}
}
